import { Map, View } from "ol";
import ScaleLine from "ol/control/ScaleLine";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { GeoJSON, WFS } from "ol/format";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { Icon, Style } from "ol/style";
import {
    equalTo as equalToFilter,
    or as orFilter,
    isNull as isNullFilter
} from "ol/format/filter";

import request from "@/utils/request";

const OGCNS = 'http://www.opengis.net/ogc';
const DOCUMENT = document.implementation.createDocument(null, null);

const data = {
    map: null,
    /**
     * 地图状态
     * normal：一般状态
     * modify：编辑状态
     */
    mapStatus: "normal",
    layers: {
        //基础地图
        basic: { name: "基础地图", visible: true, layer: null },
        //线路
        line: {
            //环评线位
            hpline: { name: "环评线位", visible: false, layer: null, features: [] },
            //施工图线位
            sgtline: { name: "施工图线位", visible: false, layer: null, features: [] }
        },
        //遥感遥测
        ygyc: {
            //遥感遥测201812
            ygyc201812: { name: "201812", visible: false, layer: null },
            //遥感遥测201912
            ygyc201906: { name: "201912", visible: false, layer: null }
        },
        //环境敏感区
        env: { name: "环境敏感区", visible: false, layer: null },
        //里程及车站
        mileageAndStation: {
            //车站
            station: {
                name: "车站", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            },
            //里程点
            mileage: {
                name: "里程点", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            }
        },
        //临时工程
        temporaryProject: {
            //弃渣场
            spoil: {
                name: "弃渣场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_spoil.png")
                    })
                })
            },
            //取土场
            fetch: {
                name: "取土场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            },
            //拌合站
            mixing: {
                name: "拌合站", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_mixing.png")
                    })
                })
            },
            //制（存）梁场
            beam: {
                name: "制（存）梁场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_beam.png")
                    })
                })
            },
            //轨枕预制场
            sleeper: {
                name: "轨枕预制场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_sleeper.png")
                    })
                })
            },
            //铺轨（架）基地
            track: {
                name: "铺轨（架）基地", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_track.png")
                    })
                })
            },
            //钢梁预拼存放场
            steel: {
                name: "钢梁预拼存放场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_steel.png")
                    })
                })
            },
            //中转料场
            transfer: {
                name: "中转料场", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_transfer.png")
                    })
                })
            },
            //临时材料厂
            temporary: {
                name: "临时材料厂", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_temporary.png")
                    })
                })
            },
            //施工营地（生活区）
            camp: {
                name: "施工营地（生活区）", visible: true, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_camp.png")
                    })
                })
            },
            //其他
            other: {
                name: "其他", visible: true, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            }
        },
        //监测点
        monitor: {
            //扬尘噪声监测
            yczsjc: {
                name: "扬尘噪声监测", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            },
            //车辆GPS
            gps: {
                name: "车辆GPS", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            },
            //隧道污水监测
            sdwsjc: {
                name: "隧道污水监测", visible: false, layer: null, features: [],
                style: new Style({
                    image: new Icon({
                        anchor: [0.5, 46],
                        anchorXUnits: "fraction",
                        anchorYUnits: "pixels",
                        src: require("@/assets/ic_other.png")
                    })
                })
            }
        }
    }
};

const methods = {
    initMap(callback) {
        data.map = new Map({
            target: "gis",
            controls: [
                new ScaleLine({
                    units: "metric"
                })
            ],
            view: new View({
                projection: "EPSG:4326",
                center: [104.0658538421, 30.6574375616],
                minZoom: 3,
                maxZoom: 20,
                zoom: 18
            })
        });
        if (callback) {
            callback(data.map);
        }
    },
    loadBaseMapLayer() {
        let layer = new TileLayer({
            source: new XYZ({
                url: process.env.VUE_APP_URL_BASE_MAP,
                minZoom: 3,
                maxZoom: 20
            })
        });
        layer.setVisible(data.layers.basic.visible);
        data.layers.basic.layer = layer;
        data.map.addLayer(layer);
    },
    loadFeatures(options) {
        let getFeatureRequest = new WFS().writeGetFeature({
            srsName: 'EPSG:4326',
            featureNS: "http://hsb.crdc.com:8771/geoserver/ewp",
            featurePrefix: "ewp",
            featureTypes: [options.layerName],
            outputFormat: 'application/json',
            filter: options.filter
        });

        let sortByNode = DOCUMENT.createElementNS(OGCNS, "SortBy");
        let sortPropertyNode = DOCUMENT.createElementNS(OGCNS, "SortProperty");
        let propertyNameNode = DOCUMENT.createElementNS(OGCNS, "PropertyName");
        propertyNameNode.textContent = "create_time";
        let sortOrderNode = DOCUMENT.createElementNS(OGCNS, "SortOrder");
        sortOrderNode.textContent = "DESC";

        sortPropertyNode.appendChild(propertyNameNode);
        sortPropertyNode.appendChild(sortOrderNode);
        sortByNode.appendChild(sortPropertyNode);
        getFeatureRequest.firstChild.appendChild(sortByNode);

        request.wfsRequest(getFeatureRequest).then(response => {
            if (response.status === 200) {
                let features = new GeoJSON().readFeatures(response.data);
                if (options.onFeatureLoaded) {
                    options.onFeatureLoaded(features);
                }
            }
        }).catch(e => {
            console.log(e);
        });
    },
    featureTransaction(options) {
        let featureTransactionRequest = new WFS().writeTransaction(options.inserts, options.updates, options.deletes, {
            // srsName: "EPSG:4326",
            featureNS: "http://hsb.crdc.com:8771/geoserver/ewp",
            featurePrefix: "ewp",
            featureType: options.layerName
        });
        return request.wfsRequest(featureTransactionRequest, "document");
    },
    loadVectorLayer(style) {
        let vectorLayer = new VectorLayer();
        vectorLayer.setStyle(style);
        let vectorSource = new VectorSource();
        vectorLayer.setSource(vectorSource);
        return vectorLayer;
    },
    loadTemporaryProjectLayers() {
        const _this = this;
        for (let layerName in data.layers.temporaryProject) {
            let filter = equalToFilter("type", layerName);
            if (layerName === "other") {
                filter = orFilter(
                    isNullFilter("type"),
                    equalToFilter("type", ""),
                    equalToFilter("type", "other")
                );
            }
            let layer = data.layers.temporaryProject[layerName].layer;
            if (!layer) {
                layer = _this.loadVectorLayer(data.layers.temporaryProject[layerName].style);
                data.layers.temporaryProject[layerName].layer = layer;
                layer.setVisible(data.layers.temporaryProject[layerName].visible);
                data.map.addLayer(layer);
            }
            _this.loadFeatures({
                layerName: "point_temporary_project",
                filter: filter,
                onFeatureLoaded: features => {
                    let vectorSource = layer.getSource();
                    vectorSource.clear();
                    vectorSource.addFeatures(features);
                    data.layers.temporaryProject[layerName].features = features;
                }
            });
        }
    },
    addTemporaryProjectFeature(feature) {
        const _this = this;
        return _this.featureTransaction({
            inserts: [feature],
            layerName: "point_temporary_project"
        });
    },
    updateTemporaryProjectFeature(feature) {
        const _this = this;
        return _this.featureTransaction({
            updates: [feature],
            layerName: "point_temporary_project"
        });
    },
    deleteTemporaryProjectFeature(feature) {
        const _this = this;
        return _this.featureTransaction({
            deletes: [feature],
            layerName: "point_temporary_project"
        });
    },
    loadAllLayers() {
        const _this = this;
        _this.loadBaseMapLayer();
        _this.loadTemporaryProjectLayers();
    },
    refreshEditableLayers() {
        const _this = this;
        _this.loadTemporaryProjectLayers();
    }
};

export {
    data as mapData,
    methods as mapMethods
};